package com.byq.mcpanus.controller;

import com.byq.mcpanus.model.Role;
import com.byq.mcpanus.model.User;
import com.byq.mcpanus.model.UserRole;
import com.byq.mcpanus.repository.RoleRepository;
import com.byq.mcpanus.repository.UserRepository;
import com.byq.mcpanus.repository.UserRoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.security.PermitAll;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class AuthController {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/register")
    @PermitAll
    public String register(@RequestParam String username, @RequestParam String password) {
        if (userRepository.findById(username).isPresent()) {
            return "用户名已存在";
        }
        Role userRole = roleRepository.findById("CUSTOMER").orElseGet(() -> {
            Role r = new Role();
            r.setId("CUSTOMER");
            return roleRepository.save(r);
        });
        User user = new User();
        user.setId(username);
        user.setPassword(passwordEncoder.encode(password));
        user = userRepository.save(user);
        UserRole userRoleRel = new UserRole();
        userRoleRel.setUserId(user.getId());
        userRoleRel.setRoleId(userRole.getId());
        userRoleRepository.save(userRoleRel);
        return "注册成功";
    }

    @PermitAll
    @PostMapping("/login")
    public UserInfo login(@RequestParam String username, @RequestParam String password, HttpServletRequest request, HttpServletResponse response) {
        User user = userRepository.findById(username).orElse(null);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        // 查找用户所有角色
        List<UserRole> userRoles = userRoleRepository.findByUserId(username);
        List<String> roleNames = userRoles.stream().map(UserRole::getRoleId).toList();
        List<SimpleGrantedAuthority> authorities = roleNames.stream()
                .map(r -> new SimpleGrantedAuthority("ROLE_" + r))
                .toList();
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                username,
                null,
                authorities
        );
        SecurityContextHolder.getContext().setAuthentication(auth);
        request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
        return new UserInfo(username, roleNames);
    }

    @GetMapping("/me")
    public ResponseEntity<UserInfo> me() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth == null || !auth.isAuthenticated() || "anonymousUser".equals(auth.getPrincipal())) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        String username = auth.getName();
        List<String> roles = auth.getAuthorities().stream()
            .map(a -> a.getAuthority().replace("ROLE_", ""))
            .toList();
        return ResponseEntity.ok(new UserInfo(username, roles));
    }
}

class UserInfo {
    private String username;
    private List<String> roles;
    public UserInfo(String username, List<String> roles) {
        this.username = username;
        this.roles = roles;
    }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public List<String> getRoles() { return roles; }
    public void setRoles(List<String> roles) { this.roles = roles; }
} 